﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Web;

namespace Landscape
{
    class CachedXmlUrlResolver : XmlUrlResolver
    {
        public override Uri ResolveUri(Uri baseUri, string relativeUri)
        {
            if (relativeUri == "-//W3C//DTD XHTML 1.0 Strict//EN")
                return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
            else if (relativeUri == "-//W3C XHTML 1.0 Transitional//EN")
                return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
            else if (relativeUri == "-//W3C//DTD XHTML 1.0 Transitional//EN")
                return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
            else if (relativeUri == "-//W3C XHTML 1.0 Frameset//EN")
                return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd");
            else if (relativeUri == "-//W3C//DTD XHTML 1.1//EN")
                return new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
            return base.ResolveUri(baseUri, relativeUri);
        }

        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {
            if (HttpRuntime.Cache[absoluteUri.AbsoluteUri] == null)
            {
                GetNewStream(absoluteUri, role, ofObjectToReturn);
            }
            Stream entity = (Stream)HttpRuntime.Cache[absoluteUri.AbsoluteUri];
            entity.Position = 0;
            return entity;
        }

        private void GetNewStream(Uri absoluteUri, string role, Type ofObjectToReturn)
        {

            // tries always to get DTD's from cache
            string URIext = Path.GetExtension(absoluteUri.AbsoluteUri).ToLower();
            string URIfile = Globals.AbsPath("/dtd/" + Path.GetFileName(absoluteUri.AbsoluteUri));
           
            if (URIext == ".dtd" && File.Exists(URIfile))
            {
                MemoryStream destStream = new MemoryStream();
                FileStream sourceStream = File.OpenRead(URIfile);
                StreamReader sourceStreamReader = new StreamReader(sourceStream);
                StreamWriter destStreamWriter = new StreamWriter(destStream);
                destStreamWriter.Write(sourceStreamReader.ReadToEnd());
                HttpRuntime.Cache.Insert(absoluteUri.AbsoluteUri, destStream, null, DateTime.Now.AddMonths(2), TimeSpan.Zero);
            }
            else {
                Stream sourceStream = (Stream)base.GetEntity(absoluteUri, role, ofObjectToReturn);
                MemoryStream destStream = new MemoryStream();
                StreamReader sourceStreamReader = new StreamReader(sourceStream);
                StreamWriter destStreamWriter = new StreamWriter(destStream);
                destStreamWriter.Write(sourceStreamReader.ReadToEnd());
                HttpRuntime.Cache.Insert(absoluteUri.AbsoluteUri, destStream, null, DateTime.Now.AddMonths(2), TimeSpan.Zero);
            }
        }

    } 

    //public class CachedXmlUrlResolver : XmlUrlResolver
    //{
    //    public static Dictionary<Uri, String> cache = new Dictionary<Uri, String>();

    //    public override Uri ResolveUri(Uri baseUri, string relativeUri)
    //    {
    //        if (relativeUri == "-//W3C//DTD XHTML 1.0 Strict//EN")
    //            return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
    //        else if (relativeUri == "-//W3C XHTML 1.0 Transitional//EN")
    //            return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
    //        else if (relativeUri == "-//W3C//DTD XHTML 1.0 Transitional//EN")
    //            return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
    //        else if (relativeUri == "-//W3C XHTML 1.0 Frameset//EN")
    //            return new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd");
    //        else if (relativeUri == "-//W3C//DTD XHTML 1.1//EN")
    //            return new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
    //        return base.ResolveUri(baseUri, relativeUri);
    //    }

    //    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    //    {
    //        if (!cache.ContainsKey(absoluteUri))
    //            GetNewStream(absoluteUri, role, ofObjectToReturn);
    //        return new FileStream(cache[absoluteUri], FileMode.Open, FileAccess.Read, FileShare.Read);
    //    }

    //    private void GetNewStream(Uri absoluteUri, string role, Type ofObjectToReturn)
    //    {
    //        using (Stream stream = (Stream)base.GetEntity(absoluteUri, role, ofObjectToReturn))
    //        {
    //            String filename = System.IO.Path.GetTempFileName();
    //            using (FileStream ms = new FileStream(filename, FileMode.Create, FileAccess.Write))
    //            {
    //                Byte[] buffer = new byte[8192];
    //                Int32 count = 0;
    //                while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
    //                {
    //                    ms.Write(buffer, 0, count);
    //                }
    //                ms.Flush();
    //                cache.Add(absoluteUri, filename);
    //            }
    //        }
    //    }

    //} 
}
